package cn.wolfcode.config;

import cn.wolfcode.domain.Employee;
import cn.wolfcode.domain.RecordLog;
import cn.wolfcode.service.IRecordLogService;
import cn.wolfcode.util.RequiredPermission;
import cn.wolfcode.util.UserContext;
import com.alibaba.fastjson.JSON;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;

@Component //把当前类注入到spring容器中
@Aspect    //把当前类标识为一个切面供容器读取
public class AopConfig {
    @Autowired
    private IRecordLogService recordLogService;
    @Autowired
    private HttpServletRequest req;
    /**
     * 指定切入点
     * 对贴有自定义注解@RequiredPermission的方法，进行切面
     */
    @Pointcut("@annotation(cn.wolfcode.util.RequiredPermission)")
    private void useMethod() {}

    /**
     * 对切入点进行增强
     */
    @Around(value = "useMethod()")
    public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        RecordLog recordLog = new RecordLog();
        Object result = null;
        //获取方法签名
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        //获取方法
        //获取一个方法
        Method method = signature.getMethod();
        //获取方法上面的注解
        RequiredPermission ano = method.getAnnotation(RequiredPermission.class);
        //判断注解是否存在
        if (ano != null){
            //获取注解上面的信息
            String anoName = ano.name();
            String expression = ano.expression();
            //设置参数
            recordLog.setOperationModule(anoName);
            recordLog.setMethod(expression);
            //获取session中的用户名
            Employee currentUser = UserContext.getCurrentUser();
            //设置用户名
            recordLog.setUsername(currentUser.getUsername());
            //获取用户Ip
            String ip = AopConfig.getIpAddress(req);
            //设置ip
            recordLog.setIp(ip);
            //设置请求参数
            Map<String, String[]> map = req.getParameterMap();
            recordLog.setArgs(JSON.toJSONString(map));
            //设置操作时间
            recordLog.setOperaionTime(new Date());
            //记录当前时间
            Long beginTime = System.currentTimeMillis();
        //执行处理方法（执行控制器中的方法）
        try {
            result = proceedingJoinPoint.proceed();
            recordLog.setResult(true);
            Long endTime = System.currentTimeMillis();
            //设置操作时长
            recordLog.setDuration(endTime-beginTime);
            recordLogService.save(recordLog);
        } catch (Exception e) {
            recordLog.setResult(false);
            recordLog.setErrorMessage(e.getMessage());
            Long endTime = System.currentTimeMillis();
            //设置操作时长
            recordLog.setDuration(endTime-beginTime);
            recordLogService.save(recordLog);
            throw e;
        }
        } else{
            result = proceedingJoinPoint.proceed();
        }
        //result是方法的返回值，直接return回去就会返回给springmvc处理
        return result;
    }

    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }


}